package Simulator.MdtGUI;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;

import Shared.AmbState;
import Shared.MapPosition;
import Simulator.LogEntry;
import Simulator.MDT;

public class MDTGUILoggedPanel extends JPanel implements Runnable {

	private AmbulancePanel ambPanel;
	private GpsPanel gpsPanel;
	private RadioPanel radioPanel;
	private MDT mdt;
	private MDTScreen parent;
	private JTabbedPane tabbedPane;
	private MDTGUILoggedPanel ref;

	private JLabel ambStatusLabel, typeLabel, positionLabel, idLabel;
	private JTextArea exchangedMsgArea;
	
	private JButton disconnectBut;

	private boolean threadLoop;

	public MDTGUILoggedPanel(MDT mdt, MDTScreen parent) {
		this.mdt = mdt;
		this.parent = parent;
		this.setLayout(new BorderLayout());
		this.ref = this;

		tabbedPane = new JTabbedPane();
		ambPanel = new AmbulancePanel();
		gpsPanel = new GpsPanel();
		radioPanel = new RadioPanel();

		tabbedPane.addTab("Ambulance", ambPanel);
		tabbedPane.addTab("GPS", gpsPanel);
		// tabbedPane.addTab("Speed", speedPanel);
		tabbedPane.addTab("Radio", radioPanel);

		JPanel backPanel = new JPanel();
		disconnectBut = new JButton("Disconnect");
		JButton crashBut = new JButton("Crash !");
		disconnectBut.addActionListener(new DisconnectListener());
		crashBut.setToolTipText("Simulates an ambulance accident");
		crashBut.addActionListener(new CrashListener());
		backPanel.add(disconnectBut);
		backPanel.add(crashBut);

		this.add(tabbedPane, BorderLayout.CENTER);
		this.add(backPanel, BorderLayout.SOUTH);

		threadLoop = true;
	}

	public int refreshData(int last_log_nb) {

		if (mdt != null) {
			if (!(mdt.isLogged())) {
				this.cleanupFields();
				this.parent.setLoginPanel();
			} else {


				idLabel.setText("" + mdt.getAmbulanceID());
				
				AmbState status = mdt.getAmbulanceStatus();
				if(status==AmbState.ASSIGNED || status==AmbState.ON_ITS_WAY || status==AmbState.BUSY || status==AmbState.CONFIRMATION_REQUESTED)
					this.disconnectBut.setEnabled(false);
				else
					this.disconnectBut.setEnabled(true);
				
				ambStatusLabel.setText(status.toString());

				typeLabel.setText(mdt.getAmbulanceType().toString());

				MapPosition pos = mdt.getAmbulancePosition();
				int[] pt = pos.getCoordinates();
				positionLabel.setText(pt[0] + ":" + pt[1]);

				List<LogEntry> logs = mdt.getLog();

				if (!logs.isEmpty() && logs.size() != (last_log_nb + 1)) {
					radioPanel.removeLogEntries(); // FIXME Go dammit WTF
													// Listeners ?
					for (int i = 0; i < logs.size(); i++) {
						LogEntry log = logs.get(i);
						radioPanel.addLogEntry(log);
						last_log_nb = i;
					}
				}
			}
		} else {

		}
		return last_log_nb;
	}

	@Override
	public void run() {
		int last_log_nb = -1;
		while (threadLoop) {
			last_log_nb = this.refreshData(last_log_nb);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void stopLoop() {
		threadLoop = false;
	}

	private void cleanupFields() {

		ambStatusLabel.setText("");
		typeLabel.setText("");
		positionLabel.setText("");
		idLabel.setText("");
		exchangedMsgArea.setText("");
	}

	class DisconnectListener implements ActionListener {

		public void actionPerformed(ActionEvent arg0) {

			if (mdt != null)
				mdt.logout();
			else
				System.err.println("MDT disconnect operation impossible : mdt==null");

			ref.cleanupFields();
			ref.parent.setLoginPanel();
			ref.parent.refreshButtons();
		}
	}

	class CrashListener implements ActionListener {

		public void actionPerformed(ActionEvent arg0) {

			if (mdt != null)
				mdt.crash();
			else
				System.err.println("MDT crash impossible : mdt==null");

			ref.cleanupFields();
			ref.parent.setLoginPanel();
			ref.parent.refreshButtons();
		}
	}

	class AmbulancePanel extends JPanel {

		public AmbulancePanel() {
			JLabel idFieldLabel = new JLabel("ID : ");
			JLabel statusFieldLabel = new JLabel("Status :");
			JLabel typeFieldLabel = new JLabel("Type :");
			JLabel positionFieldLabel = new JLabel("Position :");

			idLabel = new JLabel("");
			ambStatusLabel = new JLabel("");
			typeLabel = new JLabel("");
			positionLabel = new JLabel("");

			Box hBox0 = Box.createHorizontalBox();
			hBox0.add(idFieldLabel);
			hBox0.add(Box.createHorizontalStrut(5));
			hBox0.add(idLabel);

			Box hBox1 = Box.createHorizontalBox();
			hBox1.add(statusFieldLabel);
			hBox1.add(Box.createHorizontalStrut(5));
			hBox1.add(ambStatusLabel);

			Box hBox2 = Box.createHorizontalBox();
			hBox2.add(typeFieldLabel);
			hBox2.add(Box.createHorizontalStrut(5));
			hBox2.add(typeLabel);

			Box hBox3 = Box.createHorizontalBox();
			hBox3.add(positionFieldLabel);
			hBox3.add(Box.createHorizontalStrut(5));
			hBox3.add(positionLabel);

			Box vBox = Box.createVerticalBox();

			vBox.add(hBox0);
			vBox.add(Box.createVerticalStrut(10));
			vBox.add(hBox1);
			vBox.add(Box.createVerticalStrut(10));
			vBox.add(hBox2);
			vBox.add(Box.createVerticalStrut(10));
			// vBox.add(hBox3);

			JPanel conteneur = new JPanel();
			conteneur.add(vBox, BorderLayout.CENTER);
			conteneur.setAlignmentX(Component.LEFT_ALIGNMENT);

			this.add(conteneur, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.CENTER,
					GridBagConstraints.CENTER, new Insets(10, 10, 10, 10), 0, 0));
		}

	}

	class GpsPanel extends JPanel {

		public GpsPanel() {
			JLabel positionFieldLabel = new JLabel("Position :");

			Box hBox1 = Box.createHorizontalBox();

			hBox1.add(positionFieldLabel);
			hBox1.add(Box.createHorizontalStrut(5));
			hBox1.add(positionLabel);

			Box vBox = Box.createVerticalBox();
			vBox.add(hBox1);

			JPanel conteneur = new JPanel();
			conteneur.add(vBox, BorderLayout.CENTER);
			conteneur.setAlignmentX(Component.LEFT_ALIGNMENT);

			this.add(conteneur, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.CENTER,
					GridBagConstraints.CENTER, new Insets(10, 10, 10, 10), 0, 0));
		}
	}

	class RadioPanel extends JPanel {
		public RadioPanel() {

			JLabel exchangedMsgFieldLabel = new JLabel("Exchanged messages :");
			exchangedMsgArea = new JTextArea();

			JScrollPane scroll = new JScrollPane(exchangedMsgArea);

			scroll.setPreferredSize(new Dimension(320, 210));

			Box hBox1 = Box.createVerticalBox();
			hBox1.add(exchangedMsgFieldLabel);
			hBox1.add(Box.createHorizontalStrut(5));
			hBox1.add(scroll);

			Box vBox = Box.createVerticalBox();
			vBox.add(hBox1);

			JPanel conteneur = new JPanel();
			conteneur.add(vBox, BorderLayout.CENTER);
			conteneur.setAlignmentX(Component.LEFT_ALIGNMENT);

			this.add(conteneur, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.CENTER,
					GridBagConstraints.CENTER, new Insets(10, 10, 10, 10), 0, 0));
		}

		public void removeLogEntries() {
			exchangedMsgArea.setText("");
		}

		public void addLogEntry(LogEntry log) {
			// XXX There are list panels that exist
			String msg = log.getMessage();
			Date date = log.getDate();

			String text = exchangedMsgArea.getText();

			Calendar calendar = new GregorianCalendar();
			calendar.setTime(date);

			String time = "" + calendar.get(Calendar.HOUR) + ":" + calendar.get(Calendar.MINUTE) + ":"
					+ calendar.get(Calendar.SECOND);
			if (log.isAReceivedMessage())
				text = "[R] " + time + " -> " + msg + "\n" + text;
			else
				text = "[S] " + time + " <- " + msg + "\n" + text;

			exchangedMsgArea.setText(text);
		}
	}
}
